﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

using HK2009.Common;
using HK2009.BusinessFacade;
using HK2009.BusinessFacadeHandler;
using HK2009.EntityQuery;
using System.Data.SqlClient;
using System.Text;
using System.Threading;
using HK2009.EntityManage;

public partial class BookingManage_ArrangeBooking : BasePage
{
    private const string MATFP_ARRANGED = "MATFP_Arranged";

    IBNBookingHandler bookingManager = new BNBookingHandler();
    ISyClientHandler clientManager = new SyClientHandler();
    string language = "";
    private DataTable contractor = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        language = Thread.CurrentThread.CurrentUICulture.ToString().ToLower();
        contractor = getBindContractor();

        if (!IsPostBack)
        {
            Session[MATFP_ARRANGED] = new List<TmpShippingOrder>();

            if (Session["UserID"] != null)
            {
                ISystemHandler sysManage = new SystemHandler();
                string strPermission = sysManage.GetLoginUserPermissions();

                if (!strPermission.Contains("1051"))
                {
                    Response.Redirect("~/NotPurview.aspx");
                    return;
                }
            }
            dataBind();
        }
    }

    private void dataBind()
    {
        BN_BookingQuery query = bookingManager.GetBookingByID(int.Parse(Request["PKID"].ToString()));
        if (query != null)
        {
            IRolePurviewHandler userManager = new RolePurviewHandler();

            lblBookingNO.Text = query.BookingNO;
            lblStatus.Text = StringUtil.GetBookingStatusName(query.Status);
            Sy_ClientQuery vendor = clientManager.GetClient(query.VendorID);
            lblVendor.Text = ("en".Equals(language) ? vendor.ENGShortName : ("zh-hk".Equals(language) ? vendor.HKShortName : vendor.CNShortName));
            UsersQuery user = userManager.GetUsers(query.BookingUser);
            if (user != null)
            {
                lblBookingUser.Text = user.UserName;
            }
            lblBookingDate.Text = query.BookingDate.ToString("yyyy-MM-dd HH:mm:ss");

            if (query.CancelUser != null && query.CancelUser != 0)
            {
                user = userManager.GetUsers(query.CancelUser);
                if (user != null)
                {
                    lblCancelUser.Text = user.UserName;
                }
            }
            if (query.CancelDate != System.DateTime.MinValue)
            {
                lblCancelDate.Text = query.CancelDate.ToString("yyyy-MM-dd HH:mm:ss");
            }

            if (query.ArrangeUser != null && query.ArrangeUser != 0)
            {
                user = userManager.GetUsers(query.ArrangeUser);
                if (user != null)
                {
                    lblArrangeUser.Text = user.UserName;
                }
            }
            if (query.ArrangeDate != System.DateTime.MinValue)
            {
                lblArrangeDate.Text = query.ArrangeDate.ToString("yyyy-MM-dd HH:mm:ss");
            }

            if (query.CAUser != null && query.CAUser != 0)
            {
                user = userManager.GetUsers(query.CAUser);
                if (user != null)
                {
                    lblCAUser.Text = user.UserName;
                }
            }
            if (query.CADate != System.DateTime.MinValue)
            {
                lblCADate.Text = query.CADate.ToString("yyyy-MM-dd HH:mm:ss");
            }

            lblRemark.Text = query.Remark;

            dataBindDtl();
        }
    }

    private void dataBindDtl()
    {
        string sqlStr = @"SELECT dtl.*, client.CNShortName as Whouse, client.HKShortName as HKWhouse, client.ENGShortName as ENGWhouse,
                            shipper.CNShortName as Shipper, shipper.HKShortName as HKShipper, shipper.ENGShortName as ENGShipper
                        FROM BN_BookingDtl dtl
                            LEFT JOIN Sy_Client client ON dtl.WhouseID = client.PKID
                            LEFT JOIN Sy_Client shipper ON dtl.ShipperID = shipper.PKID
                            WHERE BookingID = @BookingID";
        SqlParameter[] parms = new SqlParameter[1];
        parms[0] = new SqlParameter("@BookingID", int.Parse(Request["PKID"].ToString()));

        DataTable dt = bookingManager.GetList(sqlStr, parms);
        DataView dv = dt.DefaultView;
        gvBookingList.DataSource = dv;
        gvBookingList.DataBind();
    }

    private DataTable getBindContractor()
    {
        ViewState["OrderBy"] = "Code";
        ViewState["Accending"] = "asc";

        string sqlStr = "SELECT client.* FROM Sy_Client client " +
                        " inner join Sy_ClientType type on client.PKID = type.ClientID " +
                        " inner join Sy_Code code on type.SyCodeID = code.PKID" +
                        " where code.Type='CT' and code.Code = 'TCGS' and client.Status = 1";
        
        DataTable dt = clientManager.GetClientList(sqlStr, null);
        return dt;
    }

    protected void btnSave_Click(object sender, EventArgs e)
    {
        List<TmpShippingOrder> arranged = new List<TmpShippingOrder>();
        List<TmpShippingOrder> newArrange = new List<TmpShippingOrder>();
        List<string> timeCheck = new List<string>();
        bool isFinish = true;
        string timeIDentifier = Guid.NewGuid().ToString();
        // 生成一个临时的Appointment用于显示
        string tmpAppointment = string.Empty;

        foreach (GridViewRow row in gvBookingList.Rows)
        {
            DropDownList ddlContractor = (DropDownList)row.FindControl("ddlContractor");
            if ("0".Equals(ddlContractor.SelectedValue))
            {
                isFinish = false;
            }
            else
            {
                HiddenField hidPKID = (HiddenField)row.FindControl("hidPKID");
                //arranged.Add(hidPKID.Value + "," + ddlContractor.SelectedValue);

                if (ddlContractor.Enabled)
                {
                    Label lblJobDate = (Label)row.FindControl("lblJobDate");
                    if (tmpAppointment == string.Empty)
                    {
                        tmpAppointment = genTmpAppointment( lblJobDate.Text.Trim());
                    }

                    if (lblJobDate.Text != null && !lblJobDate.Text.Trim().Equals(""))
                    {
                        newArrange.Add(new TmpShippingOrder(int.Parse(hidPKID.Value), 
                            int.Parse(ddlContractor.SelectedValue), tmpAppointment, timeIDentifier, lblJobDate.Text));
                    }
                    else
                    {
                        newArrange.Add(new TmpShippingOrder(int.Parse(hidPKID.Value), 
                            int.Parse(ddlContractor.SelectedValue), "", timeIDentifier, string.Empty));
                    }
                    timeCheck.Add(ddlContractor.SelectedValue);
                }
            }
        }

        if (timeCheck.Count > 0)
        {
            string tc = timeCheck[0];
            foreach (string str in timeCheck)
            {
                if (!str.Equals(tc))
                {
                    Jscript.AlertInAjax("Contractor can not be different!", UpdatePanel1);
                    //dataBind();
                    return;
                }
            }
        }

        List<TmpShippingOrder> sessionArrange = (List<TmpShippingOrder>)Session[MATFP_ARRANGED];
        sessionArrange.AddRange(newArrange);
        Session[MATFP_ARRANGED] = sessionArrange;
        arranged = sessionArrange;

        if (!isFinish)
        {
            dataBind();
            return;
        }

        int bookingID = int.Parse(Request["PKID"].ToString());
        BN_BookingQuery query = bookingManager.GetBookingByID(bookingID);

        if (query != null)
        {
            if (query.Status.ToString() != HK2009.Common.Enums.BookingStatus.NEW.ToString("d") && query.Status.ToString() != HK2009.Common.Enums.BookingStatus.CANCELARRANGED.ToString("d"))
            {
                Jscript.AlertInAjax("Booking" + Resources.Messages.WrongStatus, UpdatePanel1);
                dataBind();
                return;
            }

            SqlParameter[] parms;
            ArrayList parmsList = new ArrayList();
            List<string> sqls = new List<string>();
            int currentUser = int.Parse(Session["UserID"].ToString());

            // 根据PKID更新BN_Booking表的Status、分配人和分配时间
            sqls.Add(@"UPDATE BN_Booking SET Status=@Status, ArrangeUser=@ArrangeUser, ArrangeDate=GETDATE() WHERE PKID=@PKID");
            parms = new SqlParameter[3];
            parms[0] = new SqlParameter("@Status", HK2009.Common.Enums.BookingStatus.ARRANGED.ToString("d"));
            parms[1] = new SqlParameter("@ArrangeUser", currentUser.ToString());
            parms[2] = new SqlParameter("@PKID", bookingID.ToString());
            parmsList.Add(parms);

            ////List<string> ctrList = new List<string>();  // 保存唯一的运输队ID及对应的@ReturnValue序号(i)，格式：ID,序号
            List<string> guidList = new List<string>();     // 保存唯一的GUID及对应的@ReturnValue序号(i)，格式：GUID,序号
            string strSql = "";                              // 保存SQL语句
            List<SqlParameter> spList = new List<SqlParameter>();  // 保存strSql语句里面的参数变量
            int i = 1;
            // INSERT ShippingOrder时用到的公用变量和值，不同的运输有不同的ShippingOrder，如果运输队相同，就共用同一个ShippingOrder
            //spList.Add(new SqlParameter("@ReturnValue","0"));
            spList.Add(new SqlParameter("@BookingID", bookingID.ToString()));
            spList.Add(new SqlParameter("@BookingNO", query.BookingNO));
            spList.Add(new SqlParameter("@BookingDate", query.BookingDate));
            spList.Add(new SqlParameter("@VendorID", query.VendorID));
            spList.Add(new SqlParameter("@NewOrderStatus", int.Parse(HK2009.Common.Enums.ShippingOrderStatus.NEW.ToString("d"))));
            spList.Add(new SqlParameter("@ArrangeUser", currentUser.ToString()));
            spList.Add(new SqlParameter("@BookingStatus1", int.Parse(HK2009.Common.Enums.BookingStatus.NEW.ToString("d"))));
            spList.Add(new SqlParameter("@BookingStatus2", int.Parse(HK2009.Common.Enums.BookingStatus.CANCELARRANGED.ToString("d"))));
            spList.Add(new SqlParameter("@BNDtlStatus", HK2009.Common.Enums.BookingNoteDtlStatus.ARRANGED.ToString("d")));

            // 生成每个guid对应的Appointment
            List<string> appointmentList = new List<string>();

            foreach (TmpShippingOrder arr in arranged)
            {
                int shippingOrderIndex = 1;

                // 添加BN_ShippingOrder和BN_ShippingOrderDtl
                string insertSO = @"SET @Appointament" + i.ToString() + @"=dbo.Fn_NextAppointment(@AppmntJobDate" + i.ToString() + @");
                                INSERT INTO BN_ShippingOrder(Contractor, OrderNO, BookingID, BookingNO, BookingDate,
                                    Status, VendorID, ArrangeUser, ArrangeDate, Appointament) 
                                    VALUES(@Contractor" + i.ToString() + @",dbo.Fn_NextOrderNO(), @BookingID, @BookingNO, @BookingDate,
                                    @NewOrderStatus, @VendorID, @ArrangeUser, GETDATE(), @Appointament" + i.ToString() + @");
                                  SET @ReturnValue" + i.ToString() + @"=@@Identity;";
                foreach (string guidSeq in guidList)
                {
                    string[] tmp = guidSeq.Split(',');
                    if (tmp[0].Equals(arr.TimeIDentifier))
                    {
                        insertSO = "";
                        shippingOrderIndex = int.Parse(tmp[1]);
                        break;
                    }
                }

                if (insertSO != "")
                {
                    guidList.Add(arr.TimeIDentifier + "," + i.ToString());
                    SqlParameter parm = new SqlParameter("@ReturnValue" + i.ToString(), 0);
                    parm.SqlDbType = SqlDbType.Int;
                    parm.Direction = ParameterDirection.Output;
                    spList.Add(parm);

                    spList.Add(new SqlParameter("@AppmntJobDate" + i.ToString(), arr.BookingDtlJobDate != null && !"".Equals(arr.BookingDtlJobDate.Trim()) ? arr.BookingDtlJobDate : ""));

                    shippingOrderIndex = i;
                    i++;
                    strSql = strSql + insertSO;
                    spList.Add(new SqlParameter("@Contractor" + shippingOrderIndex.ToString(), arr.ContractorID));
                    spList.Add(new SqlParameter("@Appointament" + shippingOrderIndex.ToString(), "000000000000000000000000"));
                }

                strSql = strSql + @"INSERT INTO BN_ShippingOrderDtl(OrderID, BookingDtlID, ShipperID, SONO, PNNO, WinStart, WinClose, JobDate,
                                           DeliveryDate, WhouseID, FCLLCL, ItemNO, PCS, CTN, GrossWT, VOL, Remark,PlaceID)
                                    SELECT @ReturnValue" + shippingOrderIndex.ToString() + @", dtl.PKID, dtl.ShipperID, dtl.SONO, dtl.PNNO, dtl.WinStart, 
                                           dtl.WinClose, dtl.JobDate,
                                           dtl.DeliveryDate, dtl.WhouseID, dtl.FCLLCL, dtl.ItemNO, dtl.PCS, dtl.CTN, dtl.GrossWT, dtl.VOL, dtl.Remark,dtl.PlaceID
                                    FROM BN_BookingDtl dtl
                                    WHERE dtl.PKID = @BookingDtlID" + arr.BookingDtlID + ";";
                spList.Add(new SqlParameter("@BookingDtlID" + arr.BookingDtlID, arr.BookingDtlID));

                // 更新BN_BookingNoteDtl表的Status和BN_BookingDtl表的Contractor
                strSql = strSql + @"UPDATE BN_BookingDtl SET Contractor=@Contractor" + shippingOrderIndex.ToString()
                            + @", Appointament=@Appointament" + shippingOrderIndex.ToString() + " WHERE PKID=@BookingDtlID" + arr.BookingDtlID + ";";
                strSql = strSql + @"UPDATE BN_BookingNoteDtl SET Status=@BNDtlStatus,ArrangeUser=@ArrangeUser, ArrangeDate=GETDATE(),Appointament=@Appointament" + shippingOrderIndex.ToString() + @" WHERE PKID=(
                                            SELECT BookingNoteDtlID FROM BN_BookingDtl WHERE PKID=@BookingDtlID" + arr.BookingDtlID + ");";

            }

            sqls.Add(strSql);
            parmsList.Add(spList.ToArray());

            if (bookingManager.BookingArrange(sqls.ToArray(), parmsList))
            {
                Jscript.AlertAndRedirectInAjax(Resources.Messages.ArrangeSuccess, "BookingDtl.aspx?id=" + bookingID.ToString() + "&rtn=BookingList.aspx", UpdatePanel1);
            }
            else
            {
                Jscript.AlertInAjax(Resources.Messages.ArrangeFailed, UpdatePanel1);
            }
        }
    }

    protected void gvBookingList_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {

            Label lblShipper = (Label)e.Row.FindControl("lblShipper");
            Label lblHKShipper = (Label)e.Row.FindControl("lblHKShipper");
            Label lblENGShipper = (Label)e.Row.FindControl("lblENGShipper");

            Label lblWhouse = (Label)e.Row.FindControl("lblWhouse");
            Label lblHKWhouse = (Label)e.Row.FindControl("lblHKWhouse");
            Label lblENGWhouse = (Label)e.Row.FindControl("lblENGWhouse");

            DropDownList ddlContractor = (DropDownList)e.Row.FindControl("ddlContractor");
            ddlContractor.DataSource = contractor;

            if ("en".Equals(language))
            {
                lblShipper.Visible = false;
                lblHKShipper.Visible = false;
                lblENGShipper.Visible = true;

                lblWhouse.Visible = false;
                lblHKWhouse.Visible = false;
                lblENGWhouse.Visible = true;

                ddlContractor.DataTextField = "ENGShortName";
            }
            else if ("zh-hk".Equals(language))
            {
                lblShipper.Visible = false;
                lblHKShipper.Visible = true;
                lblENGShipper.Visible = false;

                lblWhouse.Visible = false;
                lblHKWhouse.Visible = true;
                lblENGWhouse.Visible = false;

                ddlContractor.DataTextField = "HKShortName";
            }
            else
            {
                lblShipper.Visible = true;
                lblHKShipper.Visible = false;
                lblENGShipper.Visible = false;

                lblWhouse.Visible = true;
                lblHKWhouse.Visible = false;
                lblENGWhouse.Visible = false;

                ddlContractor.DataTextField = "CNShortName";
            }

            ddlContractor.DataValueField = "PKID";
            ddlContractor.DataBind();
            ddlContractor.Items.Insert(0, new ListItem(Resources.Messages.PleaseSelect, "0"));

            HiddenField hidPKID = (HiddenField)e.Row.FindControl("hidPKID");
            List<TmpShippingOrder> newArrange = (List<TmpShippingOrder>)Session[MATFP_ARRANGED];
            Label lblAppointment = (Label)e.Row.FindControl("lblAppointment");
            foreach (TmpShippingOrder newArr in newArrange)
            {
                if (hidPKID.Value.Equals(newArr.BookingDtlID.ToString()))
                {

                    ddlContractor.SelectedValue = newArr.ContractorID.ToString();
                    ddlContractor.Enabled = false;

                    lblAppointment.Text = newArr.TmpAppointment;
                    break;
                }
            }
        }
    }

    /// <summary>
    /// 生成一个临时的Appointment，非真实的
    /// </summary>
    /// <returns></returns>
    private string genTmpAppointment(string date)
    {
        if ("".Equals(date))
        {
            return "";
        }

        List<TmpShippingOrder> existsAppList = (List<TmpShippingOrder>)Session[MATFP_ARRANGED];
        int seq = 0;
        string jobDate = String.Format("yyMM", date);
        string sl = "SL-" + jobDate;
        

        foreach (TmpShippingOrder appmnt in existsAppList)
        {
            if (appmnt.BookingDtlJobDate.Substring(0, 7).Equals(sl))
            {
                int tmpSeq = int.Parse(appmnt.BookingDtlJobDate.Substring(8));
                if (tmpSeq > seq)
                {
                    seq = tmpSeq;
                }
            }
            
        }

        if (seq == 0)
        {
            return bookingManager.GetAppointament(date.ToString());
        }
        else
        {
            seq = seq + 1;
        }

        DateTime now = DateTime.Now;

        return sl + "-" + seq.ToString();
    }
}

class TmpShippingOrder
{
    #region Construct

    public TmpShippingOrder()
    {
    }

    public TmpShippingOrder(int bookingDtlID, int contractorID, string tmpAppointment, 
        string timeIdentifier, string bookingDtlJobDate)
    {
        this.bookingDtlID = bookingDtlID;
        this.contractorID = contractorID;
        this.tmpAppointment = tmpAppointment;
        this.TimeIDentifier = timeIdentifier;
        this.bookingDtlJobDate = bookingDtlJobDate;
    }

    #endregion

    #region Properties

    private int bookingDtlID;
    public int BookingDtlID
    {
        get
        {
            return bookingDtlID;
        }
        set
        {
            bookingDtlID = value;
        }
    }

    private int contractorID;
    public int ContractorID
    {
        get
        {
            return contractorID;
        }
        set
        {
            contractorID = value;
        }
    }

    private string tmpAppointment;
    public string TmpAppointment
    {
        get
        {
            return tmpAppointment;
        }
        set
        {
            tmpAppointment = value;
        }
    }

    private string timeIDentifier;
    public string TimeIDentifier
    {
        get
        {
            return timeIDentifier;
        }
        set
        {
            timeIDentifier = value;
        }
    }

    private string bookingDtlJobDate;
    public string BookingDtlJobDate
    {
        get
        {
            return bookingDtlJobDate;
        }
        set
        {
            bookingDtlJobDate = value;
        }
    }

    #endregion
}